#pragma once

#include <string>
#include <Windows.h>


namespace Zaf {
namespace Mwl {
namespace __Internal {


class WindowState {

public:
	virtual ~WindowState() { }

	virtual void IsEnable(bool value) = 0;

	virtual HWND GetParentHandle() const = 0;
	virtual void GetSize(unsigned int& width, unsigned int& height) const = 0;
	virtual void GetPosition(unsigned int& x, unsigned int& y) const = 0;
	virtual unsigned int GetStyle() const = 0;
	virtual unsigned int GetExStyle() const = 0;
	virtual std::wstring GetText() const = 0;

	virtual void SetParentHandle(HWND value) = 0;
	virtual void SetSize(unsigned int width, unsigned int height) = 0;
	virtual void SetPosition(unsigned int x, unsigned int y) = 0;
	virtual void SetStyle(unsigned int value) = 0;
	virtual void SetExStyle(unsigned int value) = 0;
	virtual void SetText(const wchar_t* value) = 0;

protected:
	WindowState() { }

private:
	WindowState(const WindowState&);
	const WindowState& operator=(const WindowState&);
};



class WindowCreatedState : public WindowState {

public:
	WindowCreatedState(HWND hwnd) : m_hwnd(hwnd) { }

	void IsEnable(bool value) {
		EnableWindow(m_hwnd, value);
	}

	HWND GetParentHandle() const;

	unsigned int GetStyle() const {
		return GetWindowLong(m_hwnd, GWL_STYLE);
	}

	unsigned int GetExStyle() const {
		return GetWindowLong(m_hwnd, GWL_EXSTYLE);
	}

	void GetSize(unsigned int& width, unsigned int& height) const;
	void GetPosition(unsigned int& x, unsigned int& y) const;
	std::wstring GetText() const;

	void SetParentHandle(HWND value) {
		::SetParent(m_hwnd, value);
	}

	void SetStyle(unsigned int value) {
		SetWindowLong(m_hwnd, GWL_STYLE, value);
	}

	void SetExStyle(unsigned int value) {
		SetWindowLong(m_hwnd, GWL_EXSTYLE, value);
	}

	void SetSize(unsigned int width, unsigned int height) {

		SetWindowPos(
			m_hwnd,
			NULL,
			0,
			0,
			width,
			height,
			SWP_NOMOVE | SWP_NOZORDER
		);
	}

	void SetPosition(unsigned int x, unsigned int y) {

		SetWindowPos(
			m_hwnd,
			NULL,
			x,
			y,
			0,
			0,
			SWP_NOSIZE | SWP_NOZORDER
		);
	}

	void SetText(const wchar_t* value) {
		SetWindowText(m_hwnd, value);
	}

private:
	HWND m_hwnd;
};



class WindowNotCreatedState : public WindowState {

public:
	WindowNotCreatedState();

	void IsEnable(bool value) {
		if (value == true) {
			m_style |= WS_DISABLED;
		}
		else {
			m_style &= ~WS_DISABLED;
		}
	}

	HWND GetParentHandle() const { return m_parent; }

	void GetSize(unsigned int& width, unsigned int& height) const {
		width = m_width;
		height = m_height;
	}

	void GetPosition(unsigned int& x, unsigned int& y) const {
		x = m_x;
		y = m_y;
	}

	unsigned int GetStyle() const {
		return m_style;
	}

	unsigned int GetExStyle() const {
		return m_exStyle;
	}

	std::wstring GetText() const {
		return m_text;
	}

	void SetParentHandle(HWND value) {
		m_parent = value;
	}

	void SetSize(unsigned int width, unsigned int height) {
		m_width = width;
		m_height = height;
	}

	void SetPosition(unsigned int x, unsigned int y) {
		m_x = x;
		m_y = y;
	}

	void SetStyle(unsigned int value) {
		m_style = value;
	}

	void SetExStyle(unsigned int value) {
		m_exStyle = value;
	}

	void SetText(const wchar_t* value) {
		m_text = value;
	}

private:
	unsigned int m_style;
	unsigned int m_exStyle;
	unsigned int m_width;
	unsigned int m_height;
	unsigned int m_x;
	unsigned int m_y;
	HWND m_parent;
	std::wstring m_text;
};


}
}
}